﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using Fasterflect;
using Kugar.Core.ExtMethod;
using Kugar.Tools.SQLHelper.SQLGenerator.BllT4;
using Kugar.Tools.SQLHelper.SQLGenerator.EntityT4;
using Kugar.Tools.SQLHelper.SQLGenerator.Helpers;
using Kugar.Tools.SQLHelper.SQLGenerator.ViewT4;
using Microsoft.Data.ConnectionUI;
using MySql.Data.MySqlClient;
using Newtonsoft.Json.Linq;
using SqlSugar;
using DbType = SqlSugar.DbType;
using MethodInvoker = System.Windows.Forms.MethodInvoker;
using Uri = System.Uri;

namespace Kugar.Tools.SQLHelper.SQLGenerator
{
    public partial class Generator : Form
    {

        public Generator()
        {
            InitializeComponent();

        }

        private string _currentPath = "";

        private ISQLBuilder _builder = null;
        private void btnBuildConnStr_Click(object sender, EventArgs e)
        {
            if (rbMsSQL.Checked)
            {
                using (DataConnectionDialog dlg = new DataConnectionDialog())
                {
                    //添加数据源
                    //dlg.DataSources.Add(DataSource.AccessDataSource);
                    //dlg.DataSources.Add(DataSource.OdbcDataSource);
                    //dlg.DataSources.Add(DataSource.OracleDataSource);
                    dlg.DataSources.Add(DataSource.SqlDataSource);
                    dlg.ConnectionString = cmbConnStr.Text;
                    dlg.SetSelectedDataProvider(DataSource.SqlDataSource, DataProvider.SqlDataProvider);
                    //dlg.DataSources.Add(DataSource.SqlFileDataSource);
                    //设置默认数据提供对象
                    dlg.SelectedDataSource = DataSource.SqlDataSource;
                    dlg.SelectedDataProvider = DataProvider.SqlDataProvider;
                    dlg.Text = "生成数据库连接字符串";
                    //只能够通过DataConnectionDialog类的静态方琺Show出对话框
                    //不同使用dialog.Show()或dialog.ShowDialog()来呈现对话框

                    try
                    {
                        if (Microsoft.Data.ConnectionUI.DataConnectionDialog.Show(dlg) == System.Windows.Forms.DialogResult.OK)
                        {
                            cmbConnStr.Text = dlg.ConnectionString;
                        }
                    }
                    catch (Exception exception)
                    {
                        dlg.ConnectionString = "";

                        if (Microsoft.Data.ConnectionUI.DataConnectionDialog.Show(dlg) == System.Windows.Forms.DialogResult.OK)
                        {
                            cmbConnStr.Text = dlg.ConnectionString;
                        }
                    }

                }
            }
            else if (rbMySQL.Checked)
            {
                MySqlConnectionStringBuilder builder = null;

                if (!string.IsNullOrWhiteSpace(cmbConnStr.Text))
                {
                    try
                    {
                        builder = new MySqlConnectionStringBuilder(cmbConnStr.Text);
                    }
                    catch (Exception exception)
                    {
                        builder = new MySqlConnectionStringBuilder();
                    }
                }
                else
                {
                    builder = new MySqlConnectionStringBuilder();
                }

                using (var dlg = new MySql.Data.VisualStudio.ConnectDialog(builder))
                {
                    dlg.StartPosition = FormStartPosition.CenterScreen;

                    if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        try
                        {
                            var pw = ControlExt.EnumChildControl(dlg).FirstOrDefault(x => x.Name == "password")?.Text;

                            //dlg..Connection.Open();
                            cmbConnStr.Text = dlg.Connection.ConnectionString;

                            if (!cmbConnStr.Text.ToStringEx().Contains("password"))
                            {
                                cmbConnStr.Text += $";password={pw}";
                            }
                        }
                        catch
                        {
                        }
                    }
                }
            }
            else if (rbSqlite.Checked)
            {
                var s = new OpenFileDialog();

                if (s.ShowDialog(this) == DialogResult.OK)
                {
                    cmbConnStr.Text = $"Data Source={s.FileName};Version=3;";
                }
            }

        }


        private void btnFoderPicker_Click(object sender, EventArgs e)
        {
            getFolderPath(cmbEntityGeneratePath);
        }

        private void btnRefreshDb_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(cmbConnStr.Text))
            {
                MessageBox.Show("请先输入连接字符串");
                return;
            }



            if (!connToDB(cmbConnStr.Text))
            {
                MessageBox.Show("连接失败");
            }
        }

        private void btnGetDbStruct_Click(object sender, EventArgs e)
        {
            //ckTableList.Items.Clear();

            //if (!string.IsNullOrWhiteSpace(cmbDbList.SelectedItem.ToStringEx()))
            //{
            //    var tbllst = _builder.GetTables(cmbDbList.SelectedItem.ToStringEx());

            //    ckTableList.Items.AddRange(tbllst);



            //}

            refreshStruct();
        }

        private void ckTableList_SelectedValueChanged(object sender, EventArgs e)
        {
            var tbl = ckTableList.SelectedItem as DbTableStructInfo;

            if (tbl != null)
            {
                dataGridView1.DataSource = tbl.Columns;

            }

        }

        private void loadConfigFromFile(string filePath, bool isMainConfig = false)
        {
            if (File.Exists(filePath))
            {
                var config = JObject.Parse(File.ReadAllText(filePath, Encoding.UTF8));
                var path = Path.GetDirectoryName(filePath);
                var entityJson = config.GetJObject("Entity");
                var dbType = config.GetInt("DbType");
                txtNamespace.Text = entityJson.GetString("LastNamespace");
                txtDbContextName.Text = entityJson.GetString("DbContextName");
                if (dbType == 0)
                {
                    rbMsSQL.Checked = true;
                }
                else if (dbType == 1)
                {
                    rbMySQL.Checked = true;
                }
                else
                {
                    rbSqlite.Checked = true;
                }
                if (entityJson != null)
                {
                    if (isMainConfig)
                    {
                        cmbConnStr.Items.AddRange(entityJson.GetJArray("ConnStr").Select(x => ((string)x).ToStringEx().Trim()).Where(x => !string.IsNullOrWhiteSpace(x)).ToArrayEx());
                        cmbConnStr.SelectedIndex = 0;
                    }
                    else
                    {
                        cmbConnStr.Items.Clear();

                        var cnn = entityJson.GetJArray("ConnStr").Select(x => x.ToStringEx()).ToArrayEx();

                        cmbConnStr.Items.AddRange(cnn);

                        cmbConnStr.SelectedIndex = 0;

                        //if (string.IsNullOrWhiteSpace(cnn))
                        //{
                        //    cmbConnStr.SelectedIndex = 0;
                        //}
                        //else
                        //{
                        //    cmbConnStr.SelectedItem = cnn;
                        //}
                    }

                    //if (cmbConnStr.Items.Count > 0)
                    //{
                    //    if (isMainConfig)
                    //    {

                    //    }
                    //    else
                    //    {

                    //    }
                    ////}

                    cmbEntityGeneratePath.Items.Clear();

                    cmbEntityGeneratePath.Items.AddRange(entityJson.GetJArray("DescFolder").Select(x => Path.Combine(path, (string)x)).Where(x => !string.IsNullOrWhiteSpace(x)).ToArrayEx());

                    if (cmbEntityGeneratePath.Items.Count > 0)
                    {
                        cmbEntityGeneratePath.SelectedIndex = 0;
                    }


                }

                var bllJson = config.GetJObject("BLL");

                if (bllJson != null)
                {
                    txtBllName.Text = bllJson.GetString("BLLName");
                    txtBLLNamespace.Text = bllJson.GetString("LastNamespace");

                    cmbBLLGeneratePath.Items.Clear();

                    cmbBLLGeneratePath.Items.AddRange(bllJson.GetJArray("DescFolder").Select(x => Path.Combine(path, (string)x)).Where(x => !string.IsNullOrWhiteSpace(x)).ToArrayEx());

                    if (cmbBLLGeneratePath.Items.Count > 0)
                    {
                        cmbBLLGeneratePath.SelectedIndex = 0;
                    }
                }

                var viewJson = config.GetJObject("Views");

                if (viewJson != null)
                {
                    txtBuildWebNamespace.Text = viewJson.GetString("LastNamespace");

                    cmbBuildWebPath.Items.Clear();
                    cmbBuildWebPath.Items.AddRange(viewJson.GetJArray("DescFolder")?.Select(x => Path.Combine(path, (string)x))?.Where(x => !string.IsNullOrWhiteSpace(x)).ToArrayEx() ?? new string[0]);

                    if (cmbBuildWebPath.Items.Count > 0)
                    {
                        cmbBuildWebPath.SelectedIndex = 0;
                    }

                    txtAreaName.Text = viewJson.GetString("AreaName");
                }

                var isContains = false;

                setStatusText("读取配置成功,请选择连接后,点击“连接并读取数据库”按钮刷新数据结构");


                foreach (ToolStripDropDownButton menuItem in menuRecConfigFiles.DropDownItems)
                {
                    if (menuItem.Tag.ToStringEx() == filePath)
                    {
                        isContains = true;
                        break;
                    }
                }

                if (!isContains)
                {
                    var title = filePath;

                    if (title.Length > 100)
                    {
                        title = filePath.Left(20) + "..." + title.Right(40);
                    }

                    var item = new ToolStripDropDownButton(title, null,
                        (s, e) =>
                        {
                            loadConfigFromFile(filePath.ToStringEx(), false);
                            lblConfigPath.Text = title;
                        });

                    item.AutoSize = true;
                    item.ToolTipText = filePath;
                    item.Width = 400;
                    item.ShowDropDownArrow = false;
                    item.Tag = filePath.ToStringEx();

                    menuRecConfigFiles.DropDownItems.Add(item);

                }

            }
            else
            {
                MessageBox.Show("文件不存在");
            }


        }

        private void saveConfigToFile(string saveFilePath = "config.json")
        {
            if (!Path.IsPathRooted(saveFilePath))
            {
                saveFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, saveFilePath);
            }

            if (!string.IsNullOrWhiteSpace(cmbEntityGeneratePath.Text) && cmbEntityGeneratePath.Items.AsEnumerable<string>().All(x => x != cmbEntityGeneratePath.Text.ToStringEx().Trim()))
            {
                cmbEntityGeneratePath.Items.Insert(0, cmbEntityGeneratePath.Text.ToStringEx().Trim());
            }

            if (!string.IsNullOrWhiteSpace(cmbConnStr.Text.ToStringEx()) && cmbConnStr.Items.AsEnumerable<string>().All(x => x != cmbConnStr.Text.ToStringEx().Trim()))
            {
                cmbConnStr.Items.Insert(0, cmbConnStr.Text.ToStringEx().Trim());
            }

            var path = Path.GetDirectoryName(saveFilePath) + Path.DirectorySeparatorChar;

            var dbType = 0;

            if (rbMsSQL.Checked)
            {
                dbType = 0;
            }
            else if (rbMySQL.Checked)
            {
                dbType = 1;
            }
            else if (rbSqlite.Checked)
            {
                dbType = 2;
            }

            var json = new JObject()
            {
                ["DbType"] = dbType,
                ["Entity"] = new JObject()
                {
                    ["ConnStr"] = cmbConnStr.Items.AsEnumerable<object>().Select(x => x.ToStringEx()).ToArrayEx().ToJArray(),
                    ["DescFolder"] = new JArray()
                    {
                        (new Uri(path, UriKind.Absolute)).MakeRelativeUri(new Uri(cmbEntityGeneratePath.Text.ToStringEx(),UriKind.Absolute))
                    },
                    ["LastNamespace"] = txtNamespace.Text.ToStringEx().Trim(),
                    ["DbContextName"] = txtDbContextName.Text.ToStringEx().Trim()
                },
                ["BLL"] = new JObject()
                {
                    ["BLLName"] = txtBllName.Text,
                    ["DescFolder"] =new JArray()
                    {
                        (new Uri(path, UriKind.Absolute)).MakeRelativeUri(new Uri(cmbBLLGeneratePath.Text.ToString(),UriKind.Absolute))
                    },
                        
                    //    (isMainConfig ? cmbBLLGeneratePath.Items.AsEnumerable<object>() : new object[]
                    //{
                    //    cmbBLLGeneratePath.Text
                    //}).Select(x =>
                    //{
                    //    try
                    //    {
                    //        return (new Uri(path, UriKind.Absolute)).MakeRelative(new Uri(x.ToString(),
                    //            UriKind.Absolute));
                    //    }
                    //    catch (Exception e)
                    //    {
                    //        return "";
                    //    }

                    //}).Where(x => !string.IsNullOrWhiteSpace(x)).ToJArray(),
                    ["LastNamespace"] = txtBLLNamespace.Text
                },
                ["Views"] = new JObject()
                {
                    ["LastNamespace"] = txtBuildWebNamespace.Text,
                    ["DescFolder"] = new JArray()
                    {
                        (new Uri(path, UriKind.Absolute)).MakeRelativeUri(new Uri(cmbBuildWebPath.Text.ToString(),UriKind.Absolute))
                    },
                    //    (isMainConfig ? cmbBuildWebPath.Items.AsEnumerable<object>() : new Object[]
                    //    {
                    //        cmbBuildWebPath.Text
                    //    }).Select(x =>
                    //{
                    //    try
                    //    {
                    //        return (new Uri(path, UriKind.Absolute)).MakeRelative(new Uri(x.ToString(),
                    //            UriKind.Absolute));
                    //    }
                    //    catch (Exception e)
                    //    {
                    //        return "";
                    //    }

                    //}).Where(x => !string.IsNullOrWhiteSpace(x)).ToJArray(),
                    ["AreaName"] = txtAreaName.Text
                }

            };

            File.WriteAllText(saveFilePath, json.ToString(), Encoding.UTF8);
        }

        private void Generator_Load(object sender, EventArgs e)
        {
            dataGridView1.AutoGenerateColumns = false;
            if (File.Exists("config.json"))
            {
                try
                {
                    var json = JObject.Parse(File.ReadAllText("config.json", Encoding.UTF8));

                    var recentConfigFiles = json.GetJArray("recentConfigFiles").Select(x => (string)x).ToArrayEx();

                    menuRecConfigFiles.DropDownItems.Clear();

                    foreach (string str in recentConfigFiles)
                    {

                        var title = str;

                        if (title.Length > 100)
                        {
                            title = title.Left(20) + "......" + title.Right(40);
                        }


                        var item = new ToolStripDropDownButton(title, null,
                            (s1, e1) =>
                            {
                                loadConfigFromFile(str, false);
                                lblConfigPath.Text = title;
                            });

                        item.AutoSize = true;
                        item.ToolTipText = str;
                        item.Width = 400;
                        item.ShowDropDownArrow = false;
                        item.Tag = str.ToStringEx();

                        menuRecConfigFiles.DropDownItems.Add(item);
                    }

                    if (recentConfigFiles.Length > 0)
                    {
                        var last = json.GetString("lastConfigFile");

                        if (!string.IsNullOrEmpty(last))
                        {
                            loadConfigFromFile(last);
                        }
                        else
                        {
                            loadConfigFromFile(recentConfigFiles[0]);
                        }
                        

                    }
                    

                }
                catch (Exception exception)
                {
                    MessageBox.Show("加载配置文件出错:" + exception.Message);
                }


                //loadConfigFromFile("config.json",true);
            }



            //cmbUsageType.SelectedIndex = 0;
            cmbFrameworkType.SelectedIndex = 1;

            dgvProc.AutoGenerateColumns = false;

            this.MaximumSize = new Size(this.Size.Width, this.Size.Height + 30);
        }

        private void cmbDbList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (rbMySQL.Checked)
            {
                var connbuilder = new MySqlConnectionStringBuilder(cmbConnStr.Text);

                connbuilder.Database = cmbDbList.SelectedItem.ToStringEx();
                //cmbConnStr.Text= connbuilder.ToString();
            }
            else if (rbMsSQL.Checked)
            {
                var connbuilder = new SqlConnectionStringBuilder(cmbConnStr.Text);

                connbuilder.InitialCatalog = cmbDbList.SelectedItem.ToStringEx();

                //cmbConnStr.Text = connbuilder.ToString();
            }

            refreshStruct();
        }

        private bool connToDB(string connStr)
        {
            try
            {
                if (rbMsSQL.Checked)
                {
                    _builder = new MSSQLBuilder(connStr);
                }
                else if (rbMySQL.Checked)
                {
                    _builder = new MySQLBuilder(connStr);
                }
                else if (rbSqlite.Checked)
                {
                    _builder = new SqliteBuilder(connStr);
                }


                cmbDbList.Items.Clear();

                panMain.Enabled = false;

                setStatusText("正在连接数据库");

                _builder.Open();

                if (!string.IsNullOrWhiteSpace(cmbConnStr.Text) && !cmbConnStr.Items.Contains(cmbConnStr.Text))
                {
                    cmbConnStr.Items.Insert(0, cmbConnStr.Text);

                    saveConfigToFile();
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
                cmbDbList.Items.Clear();
                panMain.Enabled = true;
                setStatusText("连接失败,请重新选择连接字符串");
                return false;
            }
            finally
            {
                panMain.Enabled = true;
            }

            var dblist = _builder.GetAllDb();

            cmbDbList.Items.AddRange(dblist);

            if (cmbDbList.Items.Count > 0)
            {
                var dbName = "";

                if (rbMySQL.Checked)
                {
                    var connbuilder = new MySqlConnectionStringBuilder(cmbConnStr.Text);
                    dbName = connbuilder.Database;
                }
                else if (rbMsSQL.Checked)
                {
                    var connbuilder = new SqlConnectionStringBuilder(cmbConnStr.Text);
                    dbName = connbuilder.InitialCatalog;
                }
                else if (rbSqlite.Checked)
                {

                }


                if (!string.IsNullOrWhiteSpace(dbName))
                {
                    cmbDbList.SelectedIndex = cmbDbList.Items.IndexOf(dbName);
                }
                else
                {
                    cmbDbList.SelectedIndex = 0;
                }
            }

            return true;
        }

        private void cmbConnStr_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(cmbConnStr.Text))
            {
                MessageBox.Show("请先输入连接字符串");
                return;
            }


            if (!connToDB(cmbConnStr.Text))
            {
                MessageBox.Show("连接失败");
            }
        }

        private void btnBuild_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtDbContextName.Text))
            {
                MessageBox.Show("请输入DbContext名称");
                txtDbContextName.Focus();
                return;
            }

            if (string.IsNullOrWhiteSpace(txtNamespace.Text))
            {
                MessageBox.Show("请输入Namespace名称");
                txtNamespace.Focus();
                return;
            }

            if (string.IsNullOrWhiteSpace(cmbEntityGeneratePath.Text))
            {
                MessageBox.Show("请选择文件输出目录");
                cmbEntityGeneratePath.Focus();
                return;
            }

            foreach (DbTableStructInfo table in ckTableList.CheckedItems)
            {
                var g = new SQLServerTableGenerator(table);

                g.Namespace = txtNamespace.Text.Trim();
                g.DbContextName = txtDbContextName.Text.Trim();

                var text = g.TransformText();

                writeToEntityFile(table.Name, text);

                setStatusText($"写入表:{table.Name}类完成");
            }

            saveConfigToFile();

            setStatusText($"写入表完成");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtDbContextName.Text))
            {
                MessageBox.Show("请输入DbContext名称");
                txtDbContextName.Focus();
                return;
            }

            if (string.IsNullOrWhiteSpace(txtNamespace.Text))
            {
                MessageBox.Show("请输入Namespace名称");
                txtNamespace.Focus();
                return;
            }

            if (string.IsNullOrWhiteSpace(cmbEntityGeneratePath.Text))
            {
                MessageBox.Show("请选择文件输出目录");
                cmbEntityGeneratePath.Focus();
                return;
            }

            var g = new SQLDbContextGenerator();
            g.Namespace = txtNamespace.Text.Trim();
            g.DbContextName = txtDbContextName.Text.Trim();
            g.Tables = ckTableList.CheckedItems.AsEnumerable<DbTableStructInfo>()/*.Select(x => x.Name)*/
                .ToArrayEx();

            if (rbMsSQL.Checked)
            {
                g.DbType = DbType.SqlServer;
            }
            else if (rbMySQL.Checked)
            {
                g.DbType = SqlSugar.DbType.MySql;
            }
            else if (rbSqlite.Checked)
            {
                g.DbType = DbType.Sqlite;
            }

            var text = g.TransformText();

            writeToEntityFile(g.DbContextName, text);

            setStatusText("写入DbContext类完成");

            saveConfigToFile();
        }

        private void refreshStruct()
        {
            ckTableList.Items.Clear();
            dataGridView1.DataSource = new DbTableInfo_Column[0];

            var dbName = cmbDbList.SelectedItem.ToStringEx();

            lblStatus.Text = "正在加载数据库:" + dbName;
            panMain.Enabled = false;

            Task.Run(() =>
            {
                if (!string.IsNullOrWhiteSpace(dbName))
                {
                    //_builder.SetDb(cmbDbList.SelectedItem.ToStringEx());

                    var tbllst = _builder.GetTables(dbName);

                    //var bllModules = tbllst.Where(x=>x.Type==0).Select(x => new TableModuleInfo()
                    //{
                    //    Checked=true,
                    //    TableName=x.Name,
                    //    BLLManager=T4SQLHelper.FirstLetterUpper(T4SQLHelper.GetModuleName(x.Name))+"Manager",
                    //    Comment=x.Comment,
                    //    Table = x
                    //}).ToArrayEx();

                    var procList = _builder.GetProcs(dbName);

                    this.Invoke(new MethodInvoker(() =>
                    {
                        ckTableList.Items.AddRange(tbllst);

                        dgvProc.DataSource = procList;

                        if (chkSelectAllTable.Checked)
                        {
                            for (int i = 0; i < ckTableList.Items.Count; i++)
                            {
                                ckTableList.SetItemChecked(i, chkSelectAllTable.Checked);
                            }
                        }

                        panMain.Enabled = true;

                        btnBuildProc.Enabled = procList.Length > 0;

                        if (txtDbContextName.Text.IsNotNullOrEmpty())
                        {
                            txtDbContextName.Text = $"{dbName}Context";
                        }


                        lblStatus.Text = "数据库:" + dbName + "加载完成";
                    }));
                }
            });
        }


        private void writeToEntityFile(string fileName, string content)
        {
            if (!Directory.Exists(cmbEntityGeneratePath.Text))
            {
                Directory.CreateDirectory(cmbEntityGeneratePath.Text);
            }

            var filePath = Path.Combine(cmbEntityGeneratePath.Text, fileName.Trim() + ".generated.cs");
            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }

            File.WriteAllText(filePath, content, Encoding.UTF8);


        }

        private void setStatusText(string text)
        {
            lblStatus.Text = text;
        }

        private void chkSelectAllTable_CheckedChanged(object sender, EventArgs e)
        {
            for (int i = 0; i < ckTableList.Items.Count; i++)
            {
                ckTableList.SetItemChecked(i, chkSelectAllTable.Checked);
            }
        }

        private void btnBuildProc_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtDbContextName.Text))
            {
                MessageBox.Show("请输入DbContext名称");
                txtDbContextName.Focus();
                return;
            }

            if (string.IsNullOrWhiteSpace(txtNamespace.Text))
            {
                MessageBox.Show("请输入Namespace名称");
                txtNamespace.Focus();
                return;
            }

            if (string.IsNullOrWhiteSpace(cmbEntityGeneratePath.Text))
            {
                MessageBox.Show("请选择文件输出目录");
                cmbEntityGeneratePath.Focus();
                return;
            }

            var g = new SQLServerProcGenerator();
            g.Namespace = txtNamespace.Text.Trim();
            g.DbContextName = txtDbContextName.Text.Trim();
            g.ProcList = (DbProcInfo[])dgvProc.DataSource;

            var text = g.TransformText();

            writeToEntityFile(g.DbContextName + ".proc.generated", text);

            if (!File.Exists(Path.Combine(cmbEntityGeneratePath.Text, $"{g.DbContextName}.proc.result.generated.cs")))
            {
                var t = new ListViewGenerator();

                t.Session = new Dictionary<string, object>()
                {
                    ["Namespace"] = txtNamespace.Text,
                    ["ProcList"] = g.ProcList
                };

                var code = t.TransformText();

                writeToEntityFile($"{g.DbContextName}.proc.result", code);
            }

            //if (!File.Exists(Path.Combine(cmbEntityGeneratePath.Text, "ProcParameter.cs")))
            //{
            //    File.WriteAllText(Path.Combine(cmbEntityGeneratePath.Text, "ProcParameter.cs"),
            //        $@"using System;
            //        using System.Collections.Generic;
            //        using System.Data;
            //        using System.Linq;
            //        using System.Text;
            //        using System.Threading.Tasks;
            //        using Kugar.Core.ExtMethod;
            //        using SqlSugar;
            //        using DbType = SqlSugar.DbType;

            //        namespace {txtNamespace.Text.Trim()}.Procedures.ProcResult
            //        {{
            //            public 
            //        }}

            //");
            //}

            setStatusText("写入存储过程类完成");

            saveConfigToFile();
        }



        private void btnBuildBLL_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(cmbBLLGeneratePath.Text))
            {
                MessageBox.Show("生成路径不能为空");
                return;
            }

            if (string.IsNullOrWhiteSpace(txtBLLNamespace.Text))
            {
                MessageBox.Show("命名空间不能为空");
                return;
            }

            saveConfigToFile();

            if (cbkBaseManager.Checked)
            {
                var template = new BLLBaseManagerGenerator();
                template.ContextName = txtDbContextName.Text.Trim();
                template.Namespace = txtBLLNamespace.Text.Trim();
                template.DbModelNamespace = txtNamespace.Text;
                template.IsNetCore = cmbFrameworkType.SelectedIndex == 1;
                var code = template.TransformText();

                writeToBLLFile("BaseManager", code);
            }

            if (ckTableList.CheckedItems.Count <= 0)
            {
                MessageBox.Show("选择要生成Manager的表");
                return;
            }

            foreach (DbTableStructInfo info in ckTableList.CheckedItems)
            {
                var template = new BLLManagerGenerator();
                template.IsAsyncEnabled = cbkBuildAsync.Checked;
                template.IsSyncEnabled = cbkBuildSync.Checked;

                template.IsBuildAdd = ckbAddMethod.Checked;
                template.IsBuildDelete = ckbBuildDelte.Checked;
                template.IsBuildExists = cbkExistsMethod.Checked;
                template.IsBuildGet = ckbGetMethod.Checked;
                template.IsBuildSetState = cbkSetStateMethod.Checked;
                template.IsBuildUpdate = cbkUpdateMethod.Checked;
                template.DbModelNamespace = txtNamespace.Text;
                template.Namespace = txtBLLNamespace.Text;
                template.Table = info;
                template.ModuleName = T4SQLHelper.GetModuleName(info.Name);
                template.ModuleBLLName = template.ModuleName + "Manager";

                var code = template.TransformText();

                writeToBLLFile(template.ModuleBLLName, code);
            }
        }

        private void btnBLLPathFinder_Click(object sender, EventArgs e)
        {
            getFolderPath(cmbBLLGeneratePath);
        }

        private void writeToBLLFile(string fileName, string content)
        {
            if (!Directory.Exists(cmbBLLGeneratePath.Text))
            {
                Directory.CreateDirectory(cmbBLLGeneratePath.Text);
            }

            var filePath = Path.Combine(cmbBLLGeneratePath.Text, fileName.Trim() + ".cs");
            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }

            File.WriteAllText(filePath, content, Encoding.UTF8);

        }

        private void writeWebFile(int type, string fileName, string content)
        {
            var filePath = Path.Combine(cmbBuildWebPath.Text, type.Switch("").Case(0, "Views").Case(1, "Models").Case(2, "Controllers"), fileName.Trim());
            var folder = Path.GetDirectoryName(filePath);
            if (!Directory.Exists(folder))
            {
                Directory.CreateDirectory(folder);
            }

            //var filePath = Path.Combine(folder, fileName.Trim());
            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }

            File.WriteAllText(filePath, content);
        }

        private string getFolderPath(ComboBox cmb)
        {
            folderBrowserDialog1.RootFolder = Environment.SpecialFolder.MyComputer;
            folderBrowserDialog1.SelectedPath = cmb.Text;

            folderBrowserDialog1.ShowNewFolderButton = true;
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                cmb.Text = folderBrowserDialog1.SelectedPath;

                if (!cmbEntityGeneratePath.Items.Contains(folderBrowserDialog1.SelectedPath))
                {
                    cmb.Items.Insert(0, folderBrowserDialog1.SelectedPath);

                    saveConfigToFile();
                }

                return folderBrowserDialog1.SelectedPath;
            }

            return "";
        }

        private void cbkSelectAllMethod_CheckedChanged(object sender, EventArgs e)
        {
            ckbAddMethod.Checked = cbkSelectAllMethod.Checked;
            ckbBuildDelte.Checked = cbkSelectAllMethod.Checked;
            cbkExistsMethod.Checked = cbkSelectAllMethod.Checked;
            ckbGetMethod.Checked = cbkSelectAllMethod.Checked;
            cbkSetStateMethod.Checked = cbkSelectAllMethod.Checked;
            cbkUpdateMethod.Checked = cbkSelectAllMethod.Checked;
        }

        private void btnBuildWebPath_Click(object sender, EventArgs e)
        {
            getFolderPath(cmbBuildWebPath);
        }

        private void btnBuildWeb_Click(object sender, EventArgs e)
        {
            foreach (DbTableStructInfo item in ckTableList.CheckedItems)
            {
                var moduleName = T4SQLHelper.GetModuleName(item.Name);

                if (cbkBuildWebController.Checked)
                {
                    var t = new ControllerGenerator()
                    {
                        ModuleName = moduleName,
                        Namespace = txtBuildWebNamespace.Text,
                        Table = item,
                        AreaName = txtAreaName.Text.ToStringEx(),
                        DbModelNamespace = txtNamespace.Text.ToStringEx()
                    };

                    var code = t.TransformText();


                    writeWebFile(2, t.ModuleName + "Controller.cs", code);
                }

                if (cbkBuildWebListView.Checked)
                {
                    var t = new ListViewGenerator();

                    t.Session = new Dictionary<string, object>()
                    {
                        ["ModuleName"] = moduleName,
                        ["Namespace"] = txtBuildWebNamespace.Text,
                        ["Table"] = item,
                        ["DbModelNamespace"] = txtNamespace.Text.ToStringEx()
                    };

                    t.Initialize();
                    var code = t.TransformText();

                    writeWebFile(0, $"{moduleName}/List.cshtml", code);
                }

                if (cbkBuildWebDetailView.Checked)
                {
                    var t = new DetailViewGenerator();

                    t.Session = new Dictionary<string, object>()
                    {
                        ["ModuleName"] = moduleName,
                        ["Namespace"] = txtBuildWebNamespace.Text,
                        ["Table"] = item,
                        ["DbModelNamespace"] = txtNamespace.Text.ToStringEx()
                    };

                    t.Initialize();
                    var code = t.TransformText();

                    writeWebFile(0, $"{moduleName}/Detail.cshtml", code);
                }

                if (cbkBuildWebListView.Checked || cbkBuildWebListView.Checked)
                {
                    var t = new ViewModelGenerator();

                    t.Session = new Dictionary<string, object>()
                    {
                        ["ModuleName"] = moduleName,
                        ["Namespace"] = txtBuildWebNamespace.Text,
                        ["Table"] = item,
                        ["DbModelNamespace"] = txtNamespace.Text.ToStringEx()
                    };

                    t.Initialize();
                    var code = t.TransformText();

                    writeWebFile(1, $"{moduleName}/Model_{moduleName}.cs", code);
                }
            }


        }

        private void btnLoadConfig_Click(object sender, EventArgs e)
        {
            openFileDialog1.CheckFileExists = true;
            openFileDialog1.Multiselect = false;

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    _currentPath = Path.GetDirectoryName(openFileDialog1.FileName);
                    loadConfigFromFile(openFileDialog1.FileName);

                    var title = openFileDialog1.FileName;

                    if (title.Length > 100)
                    {
                        title = title.Left(20) + "..." + title.Right(40);
                    }

                    lblConfigPath.Text = title;
                    lblConfigPath.Tag = openFileDialog1.FileName;

                    setStatusText("读取配置成功,请选择连接后,点击“连接并读取数据库”按钮刷新数据结构");
                }
                catch (Exception exception)
                {
                    MessageBox.Show("无法加载配置文件:" + exception.Message);
                }
            }
        }

        private void btnSaveAs_Click(object sender, EventArgs e)
        {
            saveFileDialog1.InitialDirectory = Path.GetFullPath(string.IsNullOrWhiteSpace(lblConfigPath.Text)
                ? Directory.GetCurrentDirectory()
                : lblConfigPath.Text);

            saveFileDialog1.FileName = "sqlhelper_config.json";

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                saveConfigToFile(saveFileDialog1.FileName );
            }
        }


        private void Generator_FormClosing(object sender, FormClosingEventArgs e)
        {
            JObject json = null;

            if (File.Exists("config.json"))
            {
                try
                {
                    json = JObject.Parse(File.ReadAllText("config.json", Encoding.UTF8));
                }
                catch (Exception exception)
                {
                }
            }

            if (json == null)
            {
                json = new JObject();
            }

            var files = menuRecConfigFiles.DropDownItems.AsEnumerable<object>()
                .Select(x => ((ToolStripDropDownItem)x).Tag.ToStringEx()).ToArrayEx();

            json["recentConfigFiles"] = files.ToJArray();

            if (!string.IsNullOrEmpty(lblConfigPath.Tag.ToStringEx()))
            {
                json["lastConfigFile"] = lblConfigPath.Tag.ToStringEx();
            }
            

            File.WriteAllText("config.json", json.ToStringEx(), Encoding.UTF8);
        }
    }

    //public class TableModuleInfo
    //{
    //    public bool Checked { set; get; }

    //    public string TableName { set; get; }

    //    public string BLLManager { set; get; }

    //    public string Comment { set; get; }

    //    public DbTableStructInfo Table { set; get; }
    //}
}
